//
// Created by hps on 24-4-13.
//

#ifndef MARKDOWNPARSER_H
#define MARKDOWNPARSER_H


#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>

namespace hps {

enum Token {
    nul = 0,
    paragraph = 1,//段落
    href = 2,//超链接
    ul = 3,//无序集
    ol = 4,//有序集
    li = 5,//列表项目
    em = 6,//斜体，表示强调
    strong = 7,//加粗
    hr = 8,//标题
    image = 9,//图片
    quote = 10,//块引用

    //标题1-6
    h1 = 11,
    h2 = 12,
    h3 = 13,
    h4 = 14,
    h5 = 15,
    h6 = 16,

    blockcode = 17,//表示计算机源代码
    code = 18,//单行代码
};

// HTML 前置标签
const std::string frontTag[] = {
    "", "<p>", "", "<ul>", "<ol>", "<li>", "<em>", "<strong>", "<hr color=#CCCCCC size=1 / > ",
    "", "<blockquote>", "<h1>", "<h2>", "<h3>", "<h4>", "<h5>", "<h6>",
    "<pre><code>", "<code>" };
// HTML 后置标签
const std::string backTag[] = {
    "", "</p>", "", "</ul>", "</ol>", "</li>", "</em>",
    "</strong>", "", "", "</blockquote>", "</h1>", "</h2>",
    "</h3>", "</h4>", "</h5>", "</h6>", "</code></pre>", "</code>" };

struct Node {
    //语法类型
    int _type;
    //孩子节点
    std::vector<Node*> _child;
    //内容
    //elem[0]:保存需要显示的内容
    //elem[1]:保存网址/路径
    std::string elem[2];

    Node(int type)
    {
        _type = type;//赋值
    }
};


class MarkDownParser {
public:
    MarkDownParser() {
        _root = new Node(nul);
    }

    MarkDownParser(const std::string filename)
    {
        _root = new Node(nul);
        _filename = filename;
    }
    ~MarkDownParser() {
        if (_root) {
            destory(_root);
        }
    }
    void transform();
    void transform(const std::string& text);
    std::vector<int> getLineCnt(const std::string& str); // 获取所有换行符的下标
    std::string getLine(std::vector<int> idxList, int targetLine, const std::string& str);
    void dfs(Node* root);//语法树转换成HTML源代码//深度优先遍历 DFS
    const char* processStr(const char* str);//去除行首空格
    void insert(Node* curNode, const char* str);//逐字符内容插入
    std::pair<int, const char*> parseType(const char* str);//解析行首语法  返回子:语法类型 + 对应内容起始位置
    bool isCutLine(const char* str);//判断水平分割线 "---"
    void html();
    std::string getHtml();
    void destory(Node* root);//销毁
private:
    Node* _root;//语法树根节点
    std::string _filename;//文件名
    std::string _content;//存放HTML文档内容
};

} // hps

#endif //MARKDOWNPARSER_H



